<template>
  <div class="app-container">
    <Breadcrumb />
    <div class="role-container">
      <div class="role-list">
        <div class="title md24">
          <span class="circle"></span>
          <span class="title-label">角色管理</span>
        </div>
        <div class="role-list-body">
          <a-input-search
            placeholder="请输入关键词"
            :allow-clear="true"
            v-model="roleName"
            @search="handelSearch"
            @clear="getRoleListData"
            @press-enter="handelSearch"
          />
          <a-scrollbar style="height: calc(100vh - 300px); overflow: scroll">
            <div
              :class="{
                'role-list-item': true,
                activeRole: userParams.activeRole == item.roleId
              }"
              v-for="(item, index) in roles"
              :key="item.roleId"
              @click="setActive(item.roleId)"
            >
              <div class="role-name">
                {{ item.roleName }}
                <span v-if="item.roleGroup" style="color: #86909c; font-size: 12px; margin-left: 10px"
                  >({{ identityOptions.find(i => i.dictValue === item.roleGroup)?.dictLabel }})</span
                >
              </div>
              <div class="operate" v-if="item.operateCode != 0">
                <img src="../../assets/images/edit.png" alt="" @click.stop="toEditRole(item, index)" />
                <img src="../../assets/images/del.png" alt="" v-if="item.operateCode != 1" @click.stop="handleAlertModal(item)" />
              </div>
            </div>
          </a-scrollbar>
        </div>
        <a-button type="primary" @click="handleRole">
          <template #icon>
            <icon-plus />
          </template>
          新建角色
        </a-button>
      </div>
      <!-- 用户 -->
      <div class="role-container-opt">
        <div class="app-container user-manage">
          <div class="title md24">
            <span class="circle"></span>
            <span class="title-label">用户管理</span>
          </div>
          <div class="user-manage-search">
            <a-space>
              <a-input-search
                style="flex: 1"
                v-model="userParams.name"
                :allow-clear="true"
                @clear="getUserList"
                placeholder="请输入关键词"
                @search="getUserList"
                @blur="getUserList"
              />
              <a-button type="primary" @click="addUser">
                <template #icon>
                  <icon-plus />
                </template>
                添加
              </a-button>
              <a-button type="outline" @click="delUsers">
                <template #icon>
                  <icon-delete />
                </template>
                删除
              </a-button>
            </a-space>
          </div>
          <a-table
            :data="data"
            :columns="userColumn"
            :bordered="false"
            row-key="userId"
            :pagination="false"
            :row-selection="{
              type: 'checkbox',
              showCheckedAll: true
            }"
            :scroll="{ y: '80vh' }"
            v-model:selectedKeys="delUserArr"
          >
            <template #nickName="{ record }">
              <a-tooltip :content="record.nickName">
                <div>{{ record.nickName.length > 6 ? record.nickName.substr(0, 5) + "..." : record.nickName }}</div>
              </a-tooltip>
            </template>
            <template #deptName="{ record }">
              <a-tooltip :content="record.depts?.map((v: any) => v.deptName).join(',')">
                <div>
                  {{
                    record.depts?.map((v: any) => v.deptName).join(",").length > 9
                      ? record.depts
                          ?.map((v: any) => v.deptName)
                          .join(",")
                          .substr(0, 9) + "..."
                      : record.depts?.map((v: any) => v.deptName).join(",")
                  }}
                </div>
              </a-tooltip>
            </template>
          </a-table>
        </div>
        <a-divider direction="vertical"></a-divider>
        <!-- 权限 -->
        <div class="app-container role-permission">
          <div class="title md24">
            <span class="circle"></span>
            <span class="title-label">角色权限</span>
          </div>
          <div class="custom-tabs">
            <div
              class="tab-item"
              :class="rolePermissionType === 'menu' && 'tab-item-active'"
              @click="setPermissionType('menu', 'edit')"
            >
              菜单权限
            </div>
            <div
              class="tab-item"
              :class="rolePermissionType === 'data' && 'tab-item-active'"
              @click="setPermissionType('data', 'edit')"
            >
              数据权限
            </div>
          </div>
          <a-scrollbar v-if="rolePermissionType === 'menu'" style="height: calc(100vh - 270px); overflow: scroll">
            <a-tree
              :checkable="true"
              v-model:half-checked-keys="halfCheckPermissions"
              check-strictly
              v-model:checked-keys="activeMenuPermissions"
              :checked-strategy="(checkedStrategy as any)"
              :data="treeData"
              :field-names="{ title: 'menuName', key: 'menuId' }"
              @check="setPermission"
            />
          </a-scrollbar>
          <a-collapse v-else :default-active-key="[0, 1]" :bordered="false" expand-icon-position="right">
            <a-collapse-item v-for="(item, index) in dataScopeLists" :key="index" :header="item.cnName">
              <a-list :bordered="false" :split="false">
                <a-radio-group v-model="item.selectedId" @change="handelSetDataScope as any">
                  <a-list-item v-for="subItem in item.items" :key="subItem.settingId">
                    <a-space>
                      <a-radio :value="subItem.settingId">
                        <a-list-item-meta :title="subItem.title"></a-list-item-meta>
                      </a-radio>
                    </a-space>
                  </a-list-item>
                </a-radio-group>
              </a-list>
            </a-collapse-item>
          </a-collapse>
        </div>
      </div>
    </div>
    <!--  新建角色抽屉 start  -->
    <add-role-drawer
      v-if="isOpenRoleDrawer"
      v-model="isOpenRoleDrawer"
      @handel-confirm="handelConfirmRole"
      @handel-close="handelClose"
      :identityOptions="identityOptions"
    />
    <!--  删除角色/账户弹窗 -->
    <a-modal
      v-model:visible="isAlertModal"
      @ok="handleDelOk"
      okText="确定"
      cancelText="取消"
      width="400px"
      :mask-closable="false"
      unmountOnClose
      :closable="false"
    >
      <div class="modal-message">
        <div class="del-name">{{ delTitle }}</div>
        <div class="del-tip">您确定要删除该角色吗?</div>
      </div>
    </a-modal>
    <!--  添加用户弹窗  -->
    <a-modal
      v-model:visible="isAddUserModal"
      @ok="handleAddUserDelOk"
      okText="确定"
      cancelText="取消"
      :width="800"
      body-style="padding: 0;height:60vh;overflow:hidden"
      :mask-closable="false"
      unmountOnClose
      :closable="false"
      @close="closeAddUserModal"
    >
      <div class="add-user-container">
        <div class="app-container add-user-container__menu">
          <div class="title md24">
            <span class="circle"></span>
            <span class="title-label">添加用户</span>
          </div>
          <a-tree
            :checked-strategy="(checkedStrategy as any)"
            :data="(sector as any)"
            @select="getaAddUserTableData"
            :field-names="{ title: 'deptName', key: 'deptId' }"
            v-model:selected-keys="userSearchParam.deptId"
          />
        </div>
        <a-divider direction="vertical" />
        <div class="app-container add-user-container__user">
          <a-input-search
            style="width: 246px; margin-bottom: 10px"
            v-model="userSearchParam.name"
            placeholder="请输入关键词"
            @search="getaAddUserTableData"
          />
          <a-table
            :data="(userData as any)"
            v-model:selectedKeys="selectedUserKeys"
            :virtual-list-props="{ height: '46vh' }"
            :pagination="false"
            row-key="userId"
            :row-selection="(rowSelection as any)"
          >
            <template #columns>
              <a-table-column title="序号" :width="64">
                <template #cell="cell">{{ cell.rowIndex + 1 }}</template>
              </a-table-column>
              <a-table-column title="员工姓名" data-index="nickName"></a-table-column>
              <a-table-column title="手机号" data-index="mobile"></a-table-column>
            </template>
          </a-table>
        </div>
      </div>
    </a-modal>
    <!--  修改角色   -->
    <a-modal v-model:visible="visible" :on-before-ok="handleBeforeOk">
      <template #title> 编辑角色</template>
      <div style="display: flex; align-items: center; margin-bottom: 10px; margin-top: 28px">
        <span style="flex-shrink: 0; margin-right: 8px">角色名称</span>
        <a-input placeholder="请输入角色名称" v-model="editRoleForm.roleName" />
      </div>
      <div style="display: flex; align-items: center">
        <span style="flex-shrink: 0; margin-right: 8px">角色身份</span>
        <a-select placeholder="选择特定角色对应的身份，没有可不选" v-model="editRoleForm.roleGroup" allow-clear>
          <a-option v-for="item in identityOptions" :key="item.dictValue" :value="item.dictValue">{{ item.dictLabel }} </a-option>
        </a-select>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { onMounted } from "vue";
import { cloneDeep, debounce } from "lodash";
import { Message } from "@arco-design/web-vue";
import AddRoleDrawer from "./components/addRoleDrawer/index.vue";
import Breadcrumb from "@/components/Breadcrumb/index.vue";
import * as roleApis from "@/apis/role";
import { deptTree } from "@/apis/dept";
import { menuTree } from "@/apis/user";
import type * as Role from "@/apis/role/type";
import type * as Dept from "@/apis/dept/type";
import { dictByType } from "@/apis";

/**
 * 角色列表参数
 */
const roleName = ref("");
/**
 * 角色列表
 */
const roles = ref<Role.RoleList[]>([]);
// 用户列表
const data = ref<Role.RolePersonnelList[]>([]);
// 菜单树
const treeData = ref<any[]>([]);
// 部门树参数
const userSearchParam = ref({ name: "", deptId: [""] });
const sector = ref<Dept.SectortreeItem[]>([]);
// 增加用户弹窗表格数据
const userData = ref<Role.RoleSearchPersonnel[]>([]);
const selectedUserKeys = ref([]);

// 处于修改状态的角色下标
const editingRole = ref(-1);
const visible = ref(false);
const editRoleForm = ref({
  roleName: ""
});
const identityOptions = ref();
const getOption = async () => {
  const { data } = await dictByType("quota_worker_type");
  identityOptions.value = data;
};
getOption();
/**
 * 用户列表参数
 */
const userParams = ref({
  name: "",
  activeRole: ""
});
const rowSelection = reactive({
  type: "checkbox",
  showCheckedAll: true,
  onlyCurrent: false
});
// 当前角色的菜单权限
const activeMenuPermissions = ref([]);
const halfCheckPermissions = ref([]);
/**
 *@desc 角色权限
 */
const rolePermissionType = ref("menu");
const addRoleFormPermissionType = ref("menu");
const checkedKeys = ref([]);
const checkedStrategy = ref("all");

const delUserArr = ref([]);
const userColumn = [
  {
    title: "员工姓名",
    slotName: "nickName"
  },
  {
    title: "部门",
    slotName: "deptName"
  }
];

/**
 *@desc 删除用户弹窗
 */
const delUsers = async () => {
  if (delUserArr.value.length == 0) {
    Message.error("请选择要移除的用户");
    return;
  }
  await roleApis.delRoleUser(userParams.value.activeRole, delUserArr.value);
  delUserArr.value = [];
  getUserList();
  Message.success("删除成功");
};
/**
 *@desc 去掉菜单多余的属性
 */
const transform = (arr: Array<any>): Array<any> => {
  const menuArr = arr.map(v => {
    const { menuId, menuName, children } = v;
    return {
      children: children ? transform(children) : [],
      menuId,
      menuName
    };
  });
  return menuArr;
};
/**
 * 查询菜单树
 */
const getMenuTree = async () => {
  const res = await menuTree();
  if (Array.isArray(res.data)) treeData.value = transform(res.data);
  filterParent(treeData.value);
};
/**
 * 查询用户列表
 */
const getUserList = async () => {
  const res = await roleApis.rolePersonnelList({ name: userParams.value.name }, userParams.value.activeRole);
  if (Array.isArray(res.data)) data.value = res.data;
};
/**
 * 查询角色列表
 */
const getRoleListData = async () => {
  const res = await roleApis.getRoleList({ name: roleName.value });
  if (Array.isArray(res.data)) roles.value = res.data;
  userParams.value.activeRole = res.data[0]?.roleId;
  if (roles.value?.length) {
    getUserList();
    getcheckTreeId(res.data[0]?.roleId);
    getRoleDataScopeList();
  }
};
/**
 * 查询部门树
 */
const getSectorTree = async () => {
  const res = await deptTree();
  sector.value = res.data as any;
  userSearchParam.value.deptId[0] = res.data[0].deptId;
};

const handelSearch = debounce(getRoleListData, 500);
/**
 * 点击修改角色名按钮
 * @param item 修改的角色
 * @param index 切换下标所在item的编辑状态
 */
const toEditRole = (item: Role.RoleList, index: number) => {
  editRoleForm.value = cloneDeep(item);
  visible.value = true;
  editingRole.value = index;
  userParams.value.activeRole = item.roleId;
};
/**
 * 保存修改的角色名
 */
const handleBeforeOk = async () => {
  if (editRoleForm.value.roleName == "") {
    Message.error("请输入角色名称");
    return false;
  }
  if (editRoleForm.value.roleName.length > 20) {
    Message.error("角色名称不能超过20个字符");
    return false;
  }
  await roleApis.editRole(
    {
      roleName: editRoleForm.value.roleName,
      roleGroup: editRoleForm.value.roleGroup
    },
    editRoleForm.value.roleId
  );
  Message.success("修改成功");
  visible.value = false;
  await getRoleListData();
  editingRole.value = -1;
};
const childId = ref<string[]>([]);
/**
 * 递归过滤出菜单子节点
 * @param arr 菜单数组
 */
const filterParent = (arr: any[]) => {
  arr.forEach((v: any) => {
    childId.value.push(v.menuId); // 父节点也加入
    if (v.children && v.children.length) {
      filterParent(v.children);
    }
    //   if (!v.children.length) {
    //     childId.value.push(v.menuId);
    //   } else {
    //     filterParent(v.children);
    //   }
  });
};
/**
 * 获取当前角色选择菜单权限的数组
 * @param id 角色ID
 */
const getcheckTreeId = async (id: string) => {
  const res = await roleApis.roleMenuListId(id);
  activeMenuPermissions.value = res.data.menuIds?.filter((v: string) => childId.value.includes(v)) || [];
};
/**
 * 选择角色时,改变样式&&获取菜单已选择
 * @param id
 */
const setActive = async (id: string) => {
  userParams.value.activeRole = id;
  getcheckTreeId(id);
  getUserList();
  getRoleDataScopeList();
};
/**
 * 切换权限类型
 */
type treeType = "add" | "edit";
const setPermissionType = (type: string, treeType: treeType = "edit") => {
  if (treeType === "add") {
    addRoleFormPermissionType.value = type;
    if (type == "menu") {
      addTreeData.value = treeData.value;
    } else {
      addTreeData.value = [];
    }
  } else {
    rolePermissionType.value = type;
    type === "menu" && getMenuTree();
    type === "data" && getDataScopeList();
  }
};
/**
 * 设置角色权限
 */
const setPermission = async () => {
  try {
    const roleName = roles.value.filter(v => v.roleId == userParams.value.activeRole)[0].roleName;
    const postData = { menuIds: [...halfCheckPermissions.value, ...activeMenuPermissions.value], roleName };
    await roleApis.editRole(postData, userParams.value.activeRole);
    Message.success("修改成功");
  } catch (error) {
    getcheckTreeId(userParams.value.activeRole);
  }
};

/**
 * 新建角色
 */
const isOpenRoleDrawer = ref(false);
const addTreeData = ref();
const addRoleDataScopeList = ref<Role.DataScopeList[]>([]);
const handleRole = async () => {
  addTreeData.value = treeData.value;
  const { data } = await roleApis.dataScopeList();
  addRoleDataScopeList.value = handelRoleEcho(data, []);
  isOpenRoleDrawer.value = true;
};
const handelConfirmRole = async (data: any) => {
  try {
    await roleApis.addRole(data);
    Message.success("添加成功");
    getRoleListData();
    isOpenRoleDrawer.value = false;
  } catch (err) {
    console.log(err, "<<<<handelConfirmRole");
  }
};
const handelClose = () => {
  isOpenRoleDrawer.value = false;
};

/**
 * @desc 删除角色/用户
 */
const isAlertModal = ref(false);
/**
 * 删除角色的名称
 * 删除角色的id
 */
const delTitle = ref("");
const delRoleId = ref("");

const handleAlertModal = (item: Role.RoleList) => {
  delTitle.value = item.roleName;
  delRoleId.value = item.roleId;
  rolePermissionType.value = "menu";
  isAlertModal.value = true;
};
/**
 * 删除角色
 */
const handleDelOk = async () => {
  await roleApis.deleteRole(delRoleId.value);
  Message.success("删除成功");
  getRoleListData();
};
/**
 * 关闭添加用户弹窗前的回调
 */
const closeAddUserModal = () => {
  userSearchParam.value.name = "";
  selectedUserKeys.value = [];
};
/**
 * 获取添加用户弹窗表格数据
 */
const getaAddUserTableData = async () => {
  const res = await roleApis.searchRoleUser({ ...userSearchParam.value, deptId: userSearchParam.value.deptId[0] });
  userData.value = res.data;
};

const isAddUserModal = ref(false);
/**
 * 打开添加用户弹窗
 */
const addUser = async () => {
  if (userSearchParam.value.deptId) getaAddUserTableData();
  isAddUserModal.value = true;
};
/**
 * 添加用户
 */
const handleAddUserDelOk = async () => {
  isAddUserModal.value = false;
  await roleApis.addRoleUser(selectedUserKeys.value, userParams.value.activeRole);
  Message.success("添加成功");
  getUserList();
};

/**
 * 数据权限
 */
const dataScopeLists = ref<Role.DataScopeList[]>([]);
let userRoleDataScope: string[] = [];
const handelRoleEcho = (data: Role.DataScopeList[], selectedIds: string[]) => {
  return (
    data?.map((item: any) => {
      return {
        ...item,
        selectedId:
          item.items?.find((v: any) => {
            return selectedIds?.length ? selectedIds.includes(v.settingId) : v.isDefault;
          })?.settingId || ""
      };
    }) || []
  );
};
const getDataScopeList = async () => {
  const { data } = await roleApis.dataScopeList();
  dataScopeLists.value = handelRoleEcho(data, userRoleDataScope);
};
const getRoleDataScopeList = async () => {
  const { data } = await roleApis.roleDataScopeList({ roleId: userParams.value.activeRole });
  userRoleDataScope = data || [];
  dataScopeLists.value = handelRoleEcho(dataScopeLists.value, userRoleDataScope);
};
const handelSetDataScope = async (settingId: string) => {
  const postData = {
    roleId: userParams.value.activeRole,
    settingId
  };
  await roleApis.setRoleDataScope(postData);
  getRoleDataScopeList();
  Message.success("设置成功");
};

onMounted(() => {
  getRoleListData();
  getMenuTree();
  getSectorTree();
});
</script>

<style scoped lang="scss">
@import "index";
</style>
